home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 August: Tool Chest / Dev.CD Aug 95 TC / Dev.CD Aug 95 TC.toast / Tool Chest / Development Tools & Languages / Dylan Related / Marlais / Marlais 0.5.9-portable sources / gc / gc_priv.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-15  |  45.3 KB  |  1,302 lines  |  [TEXT/ttxt]

  1. /* 
  2.  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  3.  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
  4.  *
  5.  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  6.  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  7.  *
  8.  * Permission is hereby granted to use or copy this program
  9.  * for any purpose,  provided the above notices are retained on all copies.
  10.  * Permission to modify the code and to distribute modified code is granted,
  11.  * provided the above notices are retained, and a notice that the code was
  12.  * modified is included with the above copyright notice.
  13.  */
  14. /* Boehm, January 30, 1995 4:01 pm PST */
  15.  
  16.  
  17. # ifndef GC_PRIVATE_H
  18. # define GC_PRIVATE_H
  19.  
  20. #if defined(mips) && defined(SYSTYPE_BSD) && defined(sony_news)
  21.     /* sony RISC NEWS, NEWSOS 4 */
  22. #   define BSD_TIME
  23.     typedef long ptrdiff_t;
  24. #endif
  25.  
  26. #if defined(mips) && defined(SYSTYPE_BSD43)
  27.     /* MIPS RISCOS 4 */
  28. #   define BSD_TIME
  29. #endif
  30.  
  31. #ifdef BSD_TIME
  32. #   include <sys/types.h>
  33. #   include <sys/time.h>
  34. #   include <sys/resource.h>
  35. #endif /* BSD_TIME */
  36.  
  37. # ifndef GC_H
  38. #   include "gc.h"
  39. # endif
  40.  
  41. typedef GC_word word;
  42. typedef GC_signed_word signed_word;
  43.  
  44. # ifndef CONFIG_H
  45. #   include "config.h"
  46. # endif
  47.  
  48. # ifndef HEADERS_H
  49. #   include "gc_hdrs.h"
  50. # endif
  51.  
  52. # ifndef bool
  53.     typedef int bool;
  54. # endif
  55. # define TRUE 1
  56. # define FALSE 0
  57.  
  58. typedef char * ptr_t;    /* A generic pointer to which we can add    */
  59.             /* byte displacements.                */
  60.             /* Preferably identical to caddr_t, if it     */
  61.             /* exists.                    */
  62.             
  63. #if defined(__STDC__)
  64. #   include <stdlib.h>
  65. #   if !(defined( sony_news ) )
  66. #       include <stddef.h>
  67. #   endif
  68.     typedef void * extern_ptr_t;
  69. #   define VOLATILE volatile
  70. #else
  71. #   ifdef MSWIN32
  72. #       include <stdlib.h>
  73. #   endif
  74.     typedef char * extern_ptr_t;
  75. #   define VOLATILE
  76. #endif
  77.  
  78. #ifdef AMIGA
  79. #   define GC_FAR __far
  80. #else
  81. #   define GC_FAR
  82. #endif
  83.  
  84. /*********************************/
  85. /*                               */
  86. /* Definitions for conservative  */
  87. /* collector                     */
  88. /*                               */
  89. /*********************************/
  90.  
  91. /*********************************/
  92. /*                               */
  93. /* Easily changeable parameters  */
  94. /*                               */
  95. /*********************************/
  96.  
  97. #define STUBBORN_ALLOC    /* Define stubborn allocation primitives    */
  98. #if defined(SRC_M3) || defined(SMALL_CONFIG)
  99. # undef STUBBORN_ALLOC
  100. #endif
  101.  
  102.  
  103. /* #define ALL_INTERIOR_POINTERS */
  104.             /* Forces all pointers into the interior of an     */
  105.             /* object to be considered valid.  Also causes the    */
  106.             /* sizes of all objects to be inflated by at least     */
  107.             /* one byte.  This should suffice to guarantee    */
  108.             /* that in the presence of a compiler that does    */
  109.             /* not perform garbage-collector-unsafe        */
  110.             /* optimizations, all portable, strictly ANSI    */
  111.             /* conforming C programs should be safely usable    */
  112.             /* with malloc replaced by GC_malloc and free    */
  113.             /* calls removed.  There are several disadvantages: */
  114.             /* 1. There are probably no interesting, portable,    */
  115.             /*    strictly ANSI    conforming C programs.        */
  116.             /* 2. This option makes it hard for the collector    */
  117.             /*    to allocate space that is not ``pointed to''  */
  118.             /*    by integers, etc.  Under SunOS 4.X with a     */
  119.             /*    statically linked libc, we empiricaly        */
  120.             /*    observed that it would be difficult to     */
  121.             /*      allocate individual objects larger than 100K.    */
  122.             /*       Even if only smaller objects are allocated,    */
  123.             /*    more swap space is likely to be needed.       */
  124.             /*    Fortunately, much of this will never be    */
  125.             /*    touched.                    */
  126.             /* If you can easily avoid using this option, do.    */
  127.             /* If not, try to keep individual objects small.    */
  128.             
  129. #define PRINTSTATS  /* Print garbage collection statistics              */
  130.             /* For less verbose output, undefine in reclaim.c     */
  131.  
  132. #define PRINTTIMES  /* Print the amount of time consumed by each garbage   */
  133.             /* collection.                                         */
  134.  
  135. #define PRINTBLOCKS /* Print object sizes associated with heap blocks,     */
  136.             /* whether the objects are atomic or composite, and    */
  137.             /* whether or not the block was found to be empty      */
  138.             /* duing the reclaim phase.  Typically generates       */
  139.             /* about one screenful per garbage collection.         */
  140. #undef PRINTBLOCKS
  141.  
  142. #define PRINTBLACKLIST     /* Print black listed blocks, i.e. values that     */
  143.             /* cause the allocator to avoid allocating certain */
  144.             /* blocks in order to avoid introducing "false       */
  145.             /* hits".                       */
  146. #undef PRINTBLACKLIST
  147.  
  148. #ifdef SILENT
  149. #  ifdef PRINTSTATS
  150. #    undef PRINTSTATS
  151. #  endif
  152. #  ifdef PRINTTIMES
  153. #    undef PRINTTIMES
  154. #  endif
  155. #  ifdef PRINTNBLOCKS
  156. #    undef PRINTNBLOCKS
  157. #  endif
  158. #endif
  159.  
  160. #if defined(PRINTSTATS) && !defined(GATHERSTATS)
  161. #   define GATHERSTATS
  162. #endif
  163.  
  164. # if defined(SOLARIS_THREADS) && !defined(SUNOS5)
  165. --> inconsistent configuration
  166. # endif
  167. # if defined(PCR) || defined(SRC_M3) || defined(SOLARIS_THREADS)
  168. #   define THREADS
  169. # endif
  170.  
  171. #if defined(SPARC)
  172. #   define ALIGN_DOUBLE  /* Align objects of size > 1 word on 2 word   */
  173.              /* boundaries.  Wasteful of memory, but       */
  174.              /* apparently required by SPARC architecture. */
  175. #   define ASM_CLEAR_CODE    /* Stack clearing is crucial, and we     */
  176.                 /* include assembly code to do it well.    */
  177. #endif
  178.  
  179. #ifdef HP_PA
  180. #   define ALIGN_DOUBLE
  181. #endif
  182.  
  183. #define MERGE_SIZES /* Round up some object sizes, so that fewer distinct */
  184.             /* free lists are actually maintained.  This applies  */
  185.             /* only to the top level routines in misc.c, not to   */
  186.             /* user generated code that calls GC_allocobj and     */
  187.             /* GC_allocaobj directly.                             */
  188.             /* Slows down average programs slightly.  May however */
  189.             /* substantially reduce fragmentation if allocation   */
  190.             /* request sizes are widely scattered.                */
  191.             /* May save significant amounts of space for obj_map  */
  192.             /* entries.                          */
  193.  
  194. /* ALIGN_DOUBLE requires MERGE_SIZES at present. */
  195. # if defined(ALIGN_DOUBLE) && !defined(MERGE_SIZES)
  196. #   define MERGE_SIZES
  197. # endif
  198.  
  199. #if defined(ALL_INTERIOR_POINTERS) && !defined(DONT_ADD_BYTE_AT_END)
  200. # define ADD_BYTE_AT_END
  201. #endif
  202.  
  203.  
  204. # define MINHINCR 16       /* Minimum heap increment, in blocks of HBLKSIZE  */
  205. # define MAXHINCR 512      /* Maximum heap increment, in blocks              */
  206.  
  207. # define TIME_LIMIT 50       /* We try to keep pause times from exceeding     */
  208.                /* this by much. In milliseconds.         */
  209.  
  210. # define BL_LIMIT (25*HBLKSIZE)
  211.                /* If we need a block of N bytes, and we have */
  212.                /* a block of N + BL_LIMIT bytes available,      */
  213.                /* and N > BL_LIMIT,                 */
  214.                /* but all possible positions in it are      */
  215.                /* blacklisted, we just use it anyway (and     */
  216.                /* print a warning, if warnings are enabled). */
  217.                /* This risks subsequently leaking the block     */
  218.                /* due to a false reference.  But not using     */
  219.                /* the block risks unreasonable immediate     */
  220.                /* heap growth.                 */
  221.  
  222. /*********************************/
  223. /*                               */
  224. /* Stack saving for debugging     */
  225. /*                               */
  226. /*********************************/
  227.  
  228. /*
  229.  * Number of frames and arguments to save in objects allocated by
  230.  * debugging allocator.
  231.  */
  232. #   define NFRAMES 6    /* Number of frames to save. Even for        */
  233.             /* alignment reasons.                */
  234. #   define NARGS 2    /* Mumber of arguments to save for each call.    */
  235.  
  236.  
  237. #ifdef SAVE_CALL_CHAIN
  238.     struct callinfo {
  239.     word ci_pc;
  240.     word ci_arg[NARGS];    /* bit-wise complement to avoid retention */
  241.     };
  242.  
  243. /* Fill in the pc and argument information for up to NFRAMES of my    */
  244. /* callers.  Ignore my frame and my callers frame.            */
  245. void GC_save_callers (/* struct callinfo info[NFRAMES] */);
  246.  
  247. void GC_print_callers (/* struct callinfo info[NFRAMES] */);
  248.  
  249. #endif
  250.  
  251.  
  252. /*********************************/
  253. /*                               */
  254. /* OS interface routines     */
  255. /*                               */
  256. /*********************************/
  257.  
  258. #ifdef BSD_TIME
  259. #   undef CLOCK_TYPE
  260. #   undef GET_TIME
  261. #   undef MS_TIME_DIFF
  262. #   define CLOCK_TYPE struct timeval
  263. #   define GET_TIME(x) { struct rusage rusage; \
  264.              getrusage (RUSAGE_SELF,  &rusage); \
  265.              x = rusage.ru_utime; }
  266. #   define MS_TIME_DIFF(a,b) ((double) (a.tv_sec - b.tv_sec) * 1000.0 \
  267.                                + (double) (a.tv_usec - b.tv_usec) / 1000.0)
  268. #else /* !BSD_TIME */
  269. #   include <time.h>
  270. #   if !defined(__STDC__) && defined(SPARC) && defined(SUNOS4)
  271.       clock_t clock();    /* Not in time.h, where it belongs    */
  272. #   endif
  273. #   if defined(FREEBSD) && !defined(CLOCKS_PER_SEC)
  274. #     include <machine/limits.h>
  275. #     define CLOCKS_PER_SEC CLK_TCK
  276. #   endif
  277. #   if !defined(CLOCKS_PER_SEC)
  278. #     define CLOCKS_PER_SEC 1000000
  279. /*
  280.  * This is technically a bug in the implementation.  ANSI requires that
  281.  * CLOCKS_PER_SEC be defined.  But at least under SunOS4.1.1, it isn't.
  282.  * Also note that the combination of ANSI C and POSIX is incredibly gross
  283.  * here. The type clock_t is used by both clock() and times().  But on
  284.  * some machines these use different notions of a clock tick,  CLOCKS_PER_SEC
  285.  * seems to apply only to clock.  Hence we use it here.  On many machines,
  286.  * including SunOS, clock actually uses units of microseconds (which are
  287.  * not really clock ticks).
  288.  */
  289. #   endif
  290. #   define CLOCK_TYPE clock_t
  291. #   define GET_TIME(x) x = clock()
  292. #   define MS_TIME_DIFF(a,b) ((unsigned long) \
  293.         (1000.0*(double)((a)-(b))/(double)CLOCKS_PER_SEC))
  294. #endif /* !BSD_TIME */
  295.  
  296. /* We use bzero and bcopy internally.  They may not be available.    */
  297. # if defined(SPARC) && defined(SUNOS4)
  298. #   define BCOPY_EXISTS
  299. # endif
  300. # if defined(M68K) && defined(AMIGA)
  301. #   define BCOPY_EXISTS
  302. # endif
  303. # if defined(M68K) && defined(NEXT)
  304. #   define BCOPY_EXISTS
  305. # endif
  306. # if defined(VAX)
  307. #   define BCOPY_EXISTS
  308. # endif
  309. # if defined(AMIGA)
  310. #   include <string.h>
  311. #   define BCOPY_EXISTS
  312. # endif
  313.  
  314. # ifndef BCOPY_EXISTS
  315. #   include <string.h>
  316. #   define BCOPY(x,y,n) memcpy(y, x, (size_t)(n))
  317. #   define BZERO(x,n)  memset(x, 0, (size_t)(n))
  318. # else
  319. #   define BCOPY(x,y,n) bcopy((char *)(x),(char *)(y),(int)(n))
  320. #   define BZERO(x,n) bzero((char *)(x),(int)(n))
  321. # endif
  322.  
  323. /* HBLKSIZE aligned allocation.  0 is taken to mean failure     */
  324. /* space is assumed to be cleared.                */
  325. # ifdef PCR
  326.     char * real_malloc();
  327. #   define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + HBLKSIZE) \
  328.                   + HBLKSIZE-1)
  329. # else
  330. #   ifdef OS2
  331.       void * os2_alloc(size_t bytes);
  332. #     define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes + HBLKSIZE) \
  333.                                     + HBLKSIZE-1)
  334. #   else
  335. #     if defined(AMIGA) || defined(NEXT)
  336. #       define GET_MEM(bytes) HBLKPTR((size_t) \
  337.                       calloc(1, (size_t)bytes + HBLKSIZE) \
  338.                                       + HBLKSIZE-1)
  339. #     else
  340. #    ifdef MSWIN32
  341.           extern ptr_t GC_win32_get_mem();
  342. #         define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
  343. #    else
  344. #      ifdef MACOS
  345. #        if defined(USE_TEMPORARY_MEMORY)
  346.         extern Ptr GC_MacTemporaryNewPtr(size_t size,
  347.                          Boolean clearMemory);
  348. #               define GET_MEM(bytes) HBLKPTR( \
  349.             GC_MacTemporaryNewPtr(bytes + HBLKSIZE, true) + HBLKSIZE-1)
  350. #        else
  351. #                 define GET_MEM(bytes) HBLKPTR( \
  352.             NewPtrClear(bytes + HBLKSIZE) + HBLKSIZE-1)
  353. #        endif
  354. #      else
  355.             extern ptr_t GC_unix_get_mem();
  356. #           define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
  357. #      endif
  358. #    endif
  359. #     endif
  360. #   endif
  361. # endif
  362.  
  363. /*
  364.  * Mutual exclusion between allocator/collector routines.
  365.  * Needed if there is more than one allocator thread.
  366.  * FASTLOCK() is assumed to try to acquire the lock in a cheap and
  367.  * dirty way that is acceptable for a few instructions, e.g. by
  368.  * inhibiting preemption.  This is assumed to have succeeded only
  369.  * if a subsequent call to FASTLOCK_SUCCEEDED() returns TRUE.
  370.  * FASTUNLOCK() is called whether or not FASTLOCK_SUCCEEDED().
  371.  * If signals cannot be tolerated with the FASTLOCK held, then
  372.  * FASTLOCK should disable signals.  The code executed under
  373.  * FASTLOCK is otherwise immune to interruption, provided it is
  374.  * not restarted.
  375.  * DCL_LOCK_STATE declares any local variables needed by LOCK and UNLOCK
  376.  * and/or DISABLE_SIGNALS and ENABLE_SIGNALS and/or FASTLOCK.
  377.  * (There is currently no equivalent for FASTLOCK.)
  378.  */  
  379. # ifdef THREADS
  380. #  ifdef PCR_OBSOLETE    /* Faster, but broken with multiple lwp's    */
  381. #    include  "th/PCR_Th.h"
  382. #    include  "th/PCR_ThCrSec.h"
  383.      extern struct PCR_Th_MLRep GC_allocate_ml;
  384. #    define DCL_LOCK_STATE  PCR_sigset_t GC_old_sig_mask
  385. #    define LOCK() PCR_Th_ML_Acquire(&GC_allocate_ml) 
  386. #    define UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml)
  387. #    define FASTLOCK() PCR_ThCrSec_EnterSys()
  388.      /* Here we cheat (a lot): */
  389. #        define FASTLOCK_SUCCEEDED() (*(int *)(&GC_allocate_ml) == 0)
  390.         /* TRUE if nobody currently holds the lock */
  391. #    define FASTUNLOCK() PCR_ThCrSec_ExitSys()
  392. #  endif
  393. #  ifdef PCR
  394. #    include <base/PCR_Base.h>
  395. #    include <th/PCR_Th.h>
  396.      extern PCR_Th_ML GC_allocate_ml;
  397. #    define DCL_LOCK_STATE \
  398.      PCR_ERes GC_fastLockRes; PCR_sigset_t GC_old_sig_mask
  399. #    define LOCK() PCR_Th_ML_Acquire(&GC_allocate_ml)
  400. #    define UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml)
  401. #    define FASTLOCK() (GC_fastLockRes = PCR_Th_ML_Try(&GC_allocate_ml))
  402. #    define FASTLOCK_SUCCEEDED() (GC_fastLockRes == PCR_ERes_okay)
  403. #    define FASTUNLOCK()  {\
  404.         if( FASTLOCK_SUCCEEDED() ) PCR_Th_ML_Release(&GC_allocate_ml); }
  405. #  endif
  406. #  ifdef SRC_M3
  407.      extern word RT0u__inCritical;
  408. #    define LOCK() RT0u__inCritical++
  409. #    define UNLOCK() RT0u__inCritical--
  410. #  endif
  411. #  ifdef SOLARIS_THREADS
  412. #    include <thread.h>
  413. #    include <signal.h>
  414.      extern mutex_t GC_allocate_ml;
  415. #    define LOCK() mutex_lock(&GC_allocate_ml);
  416. #    define UNLOCK() mutex_unlock(&GC_allocate_ml);
  417. #  endif
  418. # else
  419. #    define LOCK()
  420. #    define UNLOCK()
  421. # endif
  422.  
  423. # ifndef DCL_LOCK_STATE
  424. #   define DCL_LOCK_STATE
  425. # endif
  426. # ifndef FASTLOCK
  427. #   define FASTLOCK() LOCK()
  428. #   define FASTLOCK_SUCCEEDED() TRUE
  429. #   define FASTUNLOCK() UNLOCK()
  430. # endif
  431.  
  432. /* Delay any interrupts or signals that may abort this thread.  Data    */
  433. /* structures are in a consistent state outside this pair of calls.    */
  434. /* ANSI C allows both to be empty (though the standard isn't very    */
  435. /* clear on that point).  Standard malloc implementations are usually    */
  436. /* neither interruptable nor thread-safe, and thus correspond to    */
  437. /* empty definitions.                            */
  438. # ifdef PCR
  439. #   define DISABLE_SIGNALS() \
  440.          PCR_Th_SetSigMask(PCR_allSigsBlocked,&GC_old_sig_mask)
  441. #   define ENABLE_SIGNALS() \
  442.         PCR_Th_SetSigMask(&GC_old_sig_mask, NIL)
  443. # else
  444. #   if defined(SRC_M3) || defined(AMIGA) || defined(SOLARIS_THREADS) \
  445.     || defined(MSWIN32) || defined(MACOS) || defined(NO_SIGNALS)
  446.             /* Also useful for debugging.        */
  447.     /* Should probably use thr_sigsetmask for SOLARIS_THREADS. */
  448. #     define DISABLE_SIGNALS()
  449. #     define ENABLE_SIGNALS()
  450. #   else
  451. #     define DISABLE_SIGNALS() GC_disable_signals()
  452.     void GC_disable_signals();
  453. #     define ENABLE_SIGNALS() GC_enable_signals()
  454.     void GC_enable_signals();
  455. #   endif
  456. # endif
  457.  
  458. /*
  459.  * Stop and restart mutator threads.
  460.  */
  461. # ifdef PCR
  462. #     include "th/PCR_ThCtl.h"
  463. #     define STOP_WORLD() \
  464.      PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_stopNormal, \
  465.                     PCR_allSigsBlocked, \
  466.                     PCR_waitForever)
  467. #     define START_WORLD() \
  468.     PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_null, \
  469.                     PCR_allSigsBlocked, \
  470.                     PCR_waitForever);
  471. # else
  472. #   ifdef SOLARIS_THREADS
  473. #     define STOP_WORLD() GC_stop_world()
  474. #     define START_WORLD() GC_start_world()
  475. #   else
  476. #     define STOP_WORLD()
  477. #     define START_WORLD()
  478. #   endif
  479. # endif
  480.  
  481. /* Abandon ship */
  482. # ifdef PCR
  483. #   define ABORT(s) PCR_Base_Panic(s)
  484. # else
  485. #   ifdef SMALL_CONFIG
  486. #    define ABORT(msg) abort();
  487. #   else
  488.     void GC_abort();
  489. #       define ABORT(msg) GC_abort(msg);
  490. #   endif
  491. # endif
  492.  
  493. /* Exit abnormally, but without making a mess (e.g. out of memory) */
  494. # ifdef PCR
  495. #   define EXIT() PCR_Base_Exit(1,PCR_waitForever)
  496. # else
  497. #   define EXIT() (void)exit(1)
  498. # endif
  499.  
  500. /* Print warning message, e.g. almost out of memory.    */
  501. # define WARN(msg,arg) (*GC_current_warn_proc)(msg, (GC_word)(arg))
  502. extern GC_warn_proc GC_current_warn_proc;
  503.  
  504. /*********************************/
  505. /*                               */
  506. /* Word-size-dependent defines   */
  507. /*                               */
  508. /*********************************/
  509.  
  510. #if CPP_WORDSZ == 32
  511. #  define WORDS_TO_BYTES(x)   ((x)<<2)
  512. #  define BYTES_TO_WORDS(x)   ((x)>>2)
  513. #  define LOGWL               ((word)5)    /* log[2] of CPP_WORDSZ */
  514. #  define modWORDSZ(n) ((n) & 0x1f)        /* n mod size of word        */
  515. #  if ALIGNMENT != 4
  516. #    define UNALIGNED
  517. #  endif
  518. #endif
  519.  
  520. #if CPP_WORDSZ == 64
  521. #  define WORDS_TO_BYTES(x)   ((x)<<3)
  522. #  define BYTES_TO_WORDS(x)   ((x)>>3)
  523. #  define LOGWL               ((word)6)    /* log[2] of CPP_WORDSZ */
  524. #  define modWORDSZ(n) ((n) & 0x3f)        /* n mod size of word        */
  525. #  if ALIGNMENT != 8
  526. #    define UNALIGNED
  527. #  endif
  528. #endif
  529.  
  530. #define WORDSZ ((word)CPP_WORDSZ)
  531. #define SIGNB  ((word)1 << (WORDSZ-1))
  532. #define BYTES_PER_WORD      ((word)(sizeof (word)))
  533. #define ONES                ((word)(-1))
  534. #define divWORDSZ(n) ((n) >> LOGWL)       /* divide n by size of word      */
  535.  
  536. /*********************/
  537. /*                   */
  538. /*  Size Parameters  */
  539. /*                   */
  540. /*********************/
  541.  
  542. /*  heap block size, bytes. Should be power of 2 */
  543.  
  544. #ifdef SMALL_CONFIG
  545. #   define CPP_LOG_HBLKSIZE 10
  546. #else
  547. # if CPP_WORDSZ == 32
  548. #   define CPP_LOG_HBLKSIZE 12
  549. # else
  550. #   define CPP_LOG_HBLKSIZE 13
  551. # endif
  552. #endif
  553. #define LOG_HBLKSIZE   ((word)CPP_LOG_HBLKSIZE)
  554. #define CPP_HBLKSIZE (1 << CPP_LOG_HBLKSIZE)
  555. #define HBLKSIZE ((word)CPP_HBLKSIZE)
  556.  
  557.  
  558. /*  max size objects supported by freelist (larger objects may be   */
  559. /*  allocated, but less efficiently)                                */
  560.  
  561. #define CPP_MAXOBJSZ    BYTES_TO_WORDS(CPP_HBLKSIZE/2)
  562. #define MAXOBJSZ ((word)CPP_MAXOBJSZ)
  563.         
  564. # define divHBLKSZ(n) ((n) >> LOG_HBLKSIZE)
  565.  
  566. # define HBLK_PTR_DIFF(p,q) divHBLKSZ((ptr_t)p - (ptr_t)q)
  567.     /* Equivalent to subtracting 2 hblk pointers.    */
  568.     /* We do it this way because a compiler should    */
  569.     /* find it hard to use an integer division    */
  570.     /* instead of a shift.  The bundled SunOS 4.1    */
  571.     /* o.w. sometimes pessimizes the subtraction to    */
  572.     /* involve a call to .div.            */
  573.  
  574. # define modHBLKSZ(n) ((n) & (HBLKSIZE-1))
  575.  
  576. # define HBLKPTR(objptr) ((struct hblk *)(((word) (objptr)) & ~(HBLKSIZE-1)))
  577.  
  578. # define HBLKDISPL(objptr) (((word) (objptr)) & (HBLKSIZE-1))
  579.  
  580. /* Round up byte allocation requests to integral number of words, etc. */
  581. # ifdef ADD_BYTE_AT_END
  582. #   define ROUNDED_UP_WORDS(n) BYTES_TO_WORDS((n) + WORDS_TO_BYTES(1))
  583. #   ifdef ALIGN_DOUBLE
  584. #       define ALIGNED_WORDS(n) (BYTES_TO_WORDS((n) + WORDS_TO_BYTES(2)) & ~1)
  585. #   else
  586. #       define ALIGNED_WORDS(n) ROUNDED_UP_WORDS(n)
  587. #   endif
  588. #   define SMALL_OBJ(bytes) ((bytes) < WORDS_TO_BYTES(MAXOBJSZ))
  589. #   define ADD_SLOP(bytes) ((bytes)+1)
  590. # else
  591. #   define ROUNDED_UP_WORDS(n) BYTES_TO_WORDS((n) + (WORDS_TO_BYTES(1) - 1))
  592. #   ifdef ALIGN_DOUBLE
  593. #       define ALIGNED_WORDS(n) \
  594.             (BYTES_TO_WORDS((n) + WORDS_TO_BYTES(2) - 1) & ~1)
  595. #   else
  596. #       define ALIGNED_WORDS(n) ROUNDED_UP_WORDS(n)
  597. #   endif
  598. #   define SMALL_OBJ(bytes) ((bytes) <= WORDS_TO_BYTES(MAXOBJSZ))
  599. #   define ADD_SLOP(bytes) (bytes)
  600. # endif
  601.  
  602.  
  603. /*
  604.  * Hash table representation of sets of pages.  This assumes it is
  605.  * OK to add spurious entries to sets.
  606.  * Used by black-listing code, and perhaps by dirty bit maintenance code.
  607.  */
  608.  
  609. # define LOG_PHT_ENTRIES  14    /* Collisions are likely if heap grows    */
  610.                 /* to more than 16K hblks = 64MB.    */
  611.                 /* Each hash table occupies 2K bytes.   */
  612. # define PHT_ENTRIES ((word)1 << LOG_PHT_ENTRIES)
  613. # define PHT_SIZE (PHT_ENTRIES >> LOGWL)
  614. typedef word page_hash_table[PHT_SIZE];
  615.  
  616. # define PHT_HASH(addr) ((((word)(addr)) >> LOG_HBLKSIZE) & (PHT_ENTRIES - 1))
  617.  
  618. # define get_pht_entry_from_index(bl, index) \
  619.         (((bl)[divWORDSZ(index)] >> modWORDSZ(index)) & 1)
  620. # define set_pht_entry_from_index(bl, index) \
  621.         (bl)[divWORDSZ(index)] |= (word)1 << modWORDSZ(index)
  622. # define clear_pht_entry_from_index(bl, index) \
  623.         (bl)[divWORDSZ(index)] &= ~((word)1 << modWORDSZ(index))
  624.     
  625.  
  626.  
  627. /********************************************/
  628. /*                                          */
  629. /*    H e a p   B l o c k s                 */
  630. /*                                          */
  631. /********************************************/
  632.  
  633. /*  heap block header */
  634. #define HBLKMASK   (HBLKSIZE-1)
  635.  
  636. #define BITS_PER_HBLK (HBLKSIZE * 8)
  637.  
  638. #define MARK_BITS_PER_HBLK (BITS_PER_HBLK/CPP_WORDSZ)
  639.        /* upper bound                                    */
  640.        /* We allocate 1 bit/word.  Only the first word   */
  641.        /* in each object is actually marked.             */
  642.  
  643. # ifdef ALIGN_DOUBLE
  644. #   define MARK_BITS_SZ (((MARK_BITS_PER_HBLK + 2*CPP_WORDSZ - 1) \
  645.               / (2*CPP_WORDSZ))*2)
  646. # else
  647. #   define MARK_BITS_SZ ((MARK_BITS_PER_HBLK + CPP_WORDSZ - 1)/CPP_WORDSZ)
  648. # endif
  649.        /* Upper bound on number of mark words per heap block  */
  650.  
  651. struct hblkhdr {
  652.     word hb_sz;  /* If in use, size in words, of objects in the block. */
  653.          /* if free, the size in bytes of the whole block      */
  654.     struct hblk * hb_next;     /* Link field for hblk free list     */
  655.                     /* and for lists of chunks waiting to be */
  656.                     /* reclaimed.                 */
  657.     word hb_descr;           /* object descriptor for marking.  See    */
  658.                     /* mark.h.                */
  659.     char* hb_map;    /* A pointer to a pointer validity map of the block. */
  660.                       /* See GC_obj_map.                     */
  661.                      /* Valid for all blocks with headers.             */
  662.                      /* Free blocks point to GC_invalid_map.             */
  663.     unsigned char hb_obj_kind;
  664.                  /* Kind of objects in the block.  Each kind     */
  665.                  /* identifies a mark procedure and a set of     */
  666.                  /* list headers.  Sometimes called regions.    */
  667.     unsigned char hb_flags;
  668. #    define IGNORE_OFF_PAGE    1    /* Ignore pointers that do not    */
  669.                     /* point to the first page of     */
  670.                     /* this object.            */
  671.     unsigned short hb_last_reclaimed;
  672.                     /* Value of GC_gc_no when block was    */
  673.                     /* last allocated or swept. May wrap.   */
  674.     word hb_marks[MARK_BITS_SZ];
  675.                 /* Bit i in the array refers to the             */
  676.                 /* object starting at the ith word (header      */
  677.                 /* INCLUDED) in the heap block.                 */
  678.                 /* The lsb of word 0 is numbered 0.            */
  679. };
  680.  
  681. /*  heap block body */
  682.  
  683. # define DISCARD_WORDS 0
  684.     /* Number of words to be dropped at the beginning of each block    */
  685.     /* Must be a multiple of WORDSZ.  May reasonably be nonzero    */
  686.     /* on machines that don't guarantee longword alignment of    */
  687.     /* pointers, so that the number of false hits is minimized.    */
  688.     /* 0 and WORDSZ are probably the only reasonable values.    */
  689.  
  690. # define BODY_SZ ((HBLKSIZE-WORDS_TO_BYTES(DISCARD_WORDS))/sizeof(word))
  691.  
  692. struct hblk {
  693. #   if (DISCARD_WORDS != 0)
  694.         word garbage[DISCARD_WORDS];
  695. #   endif
  696.     word hb_body[BODY_SZ];
  697. };
  698.  
  699. # define HDR_WORDS ((word)DISCARD_WORDS)
  700. # define HDR_BYTES ((word)WORDS_TO_BYTES(DISCARD_WORDS))
  701.  
  702. # define OBJ_SZ_TO_BLOCKS(sz) \
  703.     divHBLKSZ(HDR_BYTES + WORDS_TO_BYTES(sz) + HBLKSIZE-1)
  704.     /* Size of block (in units of HBLKSIZE) needed to hold objects of    */
  705.     /* given sz (in words).                        */
  706.  
  707. /* Object free list link */
  708. # define obj_link(p) (*(ptr_t *)(p))
  709.  
  710. /*  lists of all heap blocks and free lists    */
  711. /* These are grouped together in a struct    */
  712. /* so that they can be easily skipped by the    */
  713. /* GC_mark routine.                */
  714. /* The ordering is weird to make GC_malloc    */
  715. /* faster by keeping the important fields    */
  716. /* sufficiently close together that a        */
  717. /* single load of a base register will do.    */
  718. /* Scalars that could easily appear to        */
  719. /* be pointers are also put here.        */
  720.  
  721. struct _GC_arrays {
  722.   word _heapsize;
  723.   word _max_heapsize;
  724.   ptr_t _last_heap_addr;
  725.   ptr_t _prev_heap_addr;
  726.   word _words_allocd_before_gc;
  727.         /* Number of words allocated before this    */
  728.         /* collection cycle.                */
  729. # ifdef GATHERSTATS
  730.     word _composite_in_use;
  731.            /* Number of words in accessible composite    */
  732.         /* objects.                    */
  733.     word _atomic_in_use;
  734.            /* Number of words in accessible atomic        */
  735.         /* objects.                    */
  736. # endif
  737.   word _words_allocd;
  738.       /* Number of words allocated during this collection cycle */
  739.   word _words_wasted;
  740.       /* Number of words wasted due to internal fragmentation     */
  741.       /* in large objects allocated since last gc. Approximate.*/
  742.   word _non_gc_bytes_at_gc;
  743.       /* Number of explicitly managed bytes of storage     */
  744.       /* at last collection.                    */
  745.   word _mem_freed;
  746.       /* Number of explicitly deallocated words of memory    */
  747.       /* since last collection.                */
  748.       
  749.   ptr_t _objfreelist[MAXOBJSZ+1];
  750.               /* free list for objects */
  751. # ifdef MERGE_SIZES
  752.     unsigned _size_map[WORDS_TO_BYTES(MAXOBJSZ+1)];
  753.         /* Number of words to allocate for a given allocation request in */
  754.         /* bytes.                             */
  755. # endif 
  756.   ptr_t _aobjfreelist[MAXOBJSZ+1];
  757.               /* free list for atomic objs     */
  758.  
  759.   ptr_t _uobjfreelist[MAXOBJSZ+1];
  760.               /* uncollectable but traced objs     */
  761.  
  762. # ifdef STUBBORN_ALLOC
  763.     ptr_t _sobjfreelist[MAXOBJSZ+1];
  764. # endif
  765.                 /* free list for immutable objects    */
  766.   ptr_t _obj_map[MAXOBJSZ+1];
  767.                        /* If not NIL, then a pointer to a map of valid  */
  768.                    /* object addresses. _obj_map[sz][i] is j if the    */
  769.                    /* address block_start+i is a valid pointer      */
  770.                    /* to an object at                */
  771.                    /* block_start+i&~3 - WORDS_TO_BYTES(j).        */
  772.                    /* (If ALL_INTERIOR_POINTERS is defined, then    */
  773.                    /* instead ((short *)(hbh_map[sz])[i] is j if    */
  774.                    /* block_start+WORDS_TO_BYTES(i) is in the    */
  775.                    /* interior of an object starting at        */
  776.                    /* block_start+WORDS_TO_BYTES(i-j)).        */
  777.                    /* It is OBJ_INVALID if                */
  778.                    /* block_start+WORDS_TO_BYTES(i) is not        */
  779.                    /* valid as a pointer to an object.              */
  780.                    /* We assume all values of j <= OBJ_INVALID.    */
  781.                    /* The zeroth entry corresponds to large objects.*/
  782. #   ifdef ALL_INTERIOR_POINTERS
  783. #    define map_entry_type short
  784. #       define OBJ_INVALID 0x7fff
  785. #    define MAP_ENTRY(map, bytes) \
  786.         (((map_entry_type *)(map))[BYTES_TO_WORDS(bytes)])
  787. #    define MAP_ENTRIES BYTES_TO_WORDS(HBLKSIZE)
  788. #    define MAP_SIZE (MAP_ENTRIES * sizeof(map_entry_type))
  789. #    define OFFSET_VALID(displ) TRUE
  790. #    define CPP_MAX_OFFSET (HBLKSIZE - HDR_BYTES - 1)
  791. #    define MAX_OFFSET ((word)CPP_MAX_OFFSET)
  792. #   else
  793. #    define map_entry_type char
  794. #       define OBJ_INVALID 0x7f
  795. #    define MAP_ENTRY(map, bytes) \
  796.         (map)[bytes]
  797. #    define MAP_ENTRIES HBLKSIZE
  798. #    define MAP_SIZE MAP_ENTRIES
  799. #    define CPP_MAX_OFFSET (WORDS_TO_BYTES(OBJ_INVALID) - 1)    
  800. #    define MAX_OFFSET ((word)CPP_MAX_OFFSET)
  801. #     define VALID_OFFSET_SZ \
  802.       (CPP_MAX_OFFSET > WORDS_TO_BYTES(CPP_MAXOBJSZ)? \
  803.        CPP_MAX_OFFSET+1 \
  804.        : WORDS_TO_BYTES(CPP_MAXOBJSZ)+1)
  805.       char _valid_offsets[VALID_OFFSET_SZ];
  806.                 /* GC_valid_offsets[i] == TRUE ==> i     */
  807.                 /* is registered as a displacement.    */
  808. #    define OFFSET_VALID(displ) GC_valid_offsets[displ]
  809.       char _modws_valid_offsets[sizeof(word)];
  810.                 /* GC_valid_offsets[i] ==>          */
  811.                 /* GC_modws_valid_offsets[i%sizeof(word)] */
  812. #   endif
  813. # ifdef STUBBORN_ALLOC
  814.       page_hash_table _changed_pages;
  815.         /* Stubborn object pages that were changes since last call to    */
  816.     /* GC_read_changed.                        */
  817.       page_hash_table _prev_changed_pages;
  818.         /* Stubborn object pages that were changes before last call to    */
  819.     /* GC_read_changed.                        */
  820. # endif
  821. # if defined(PROC_VDB) || defined(MPROTECT_VDB)
  822.       page_hash_table _grungy_pages; /* Pages that were dirty at last        */
  823.                      /* GC_read_dirty.               */
  824. # endif
  825. # define MAX_HEAP_SECTS 256    /* Separately added heap sections. */
  826.   struct HeapSect {
  827.       ptr_t hs_start; word hs_bytes;
  828.   } _heap_sects[MAX_HEAP_SECTS];
  829. # ifdef MSWIN32
  830.     ptr_t _heap_bases[MAX_HEAP_SECTS];
  831.             /* Start address of memory regions obtained from kernel. */
  832. # endif
  833.   /* Block header index; see gc_headers.h */
  834.   bottom_index * _all_nils;
  835.   bottom_index * _top_index [TOP_SZ];
  836. #ifdef SAVE_CALL_CHAIN
  837.   struct callinfo _last_stack[NFRAMES];    /* Stack at last garbage collection.*/
  838.                       /* Useful for debugging    mysterious  */
  839.                       /* object disappearances.        */
  840.                       /* In the multithreaded case, we    */
  841.                       /* currently only save the calling  */
  842.                       /* stack.                */
  843. #endif
  844. };
  845.  
  846. extern GC_FAR struct _GC_arrays GC_arrays; 
  847.  
  848. # define GC_objfreelist GC_arrays._objfreelist
  849. # define GC_aobjfreelist GC_arrays._aobjfreelist
  850. # define GC_uobjfreelist GC_arrays._uobjfreelist
  851. # define GC_sobjfreelist GC_arrays._sobjfreelist
  852. # define GC_valid_offsets GC_arrays._valid_offsets
  853. # define GC_modws_valid_offsets GC_arrays._modws_valid_offsets
  854. # ifdef STUBBORN_ALLOC
  855. #    define GC_changed_pages GC_arrays._changed_pages
  856. #    define GC_prev_changed_pages GC_arrays._prev_changed_pages
  857. # endif
  858. # define GC_obj_map GC_arrays._obj_map
  859. # define GC_last_heap_addr GC_arrays._last_heap_addr
  860. # define GC_prev_heap_addr GC_arrays._prev_heap_addr
  861. # define GC_words_allocd GC_arrays._words_allocd
  862. # define GC_words_wasted GC_arrays._words_wasted
  863. # define GC_non_gc_bytes_at_gc GC_arrays._non_gc_bytes_at_gc
  864. # define GC_mem_freed GC_arrays._mem_freed
  865. # define GC_heapsize GC_arrays._heapsize
  866. # define GC_max_heapsize GC_arrays._max_heapsize
  867. # define GC_words_allocd_before_gc GC_arrays._words_allocd_before_gc
  868. # define GC_heap_sects GC_arrays._heap_sects
  869. # define GC_last_stack GC_arrays._last_stack
  870. # ifdef MSWIN32
  871. #   define GC_heap_bases GC_arrays._heap_bases
  872. # endif
  873. # define GC_all_nils GC_arrays._all_nils
  874. # define GC_top_index GC_arrays._top_index
  875. # if defined(PROC_VDB) || defined(MPROTECT_VDB)
  876. #   define GC_grungy_pages GC_arrays._grungy_pages
  877. # endif
  878. # ifdef GATHERSTATS
  879. #   define GC_composite_in_use GC_arrays._composite_in_use
  880. #   define GC_atomic_in_use GC_arrays._atomic_in_use
  881. # endif
  882. # ifdef MERGE_SIZES
  883. #   define GC_size_map GC_arrays._size_map
  884. # endif
  885.  
  886. # define beginGC_arrays ((ptr_t)(&GC_arrays))
  887. # define endGC_arrays (((ptr_t)(&GC_arrays)) + (sizeof GC_arrays))
  888.  
  889.  
  890. # define MAXOBJKINDS 16
  891.  
  892. /* Object kinds: */
  893. extern struct obj_kind {
  894.    ptr_t *ok_freelist;    /* Array of free listheaders for this kind of object */
  895.                /* Point either to GC_arrays or to storage allocated */
  896.                /* with GC_scratch_alloc.                 */
  897.    struct hblk **ok_reclaim_list;
  898.                /* List headers for lists of blocks waiting to be */
  899.                /* swept.                      */
  900.    word ok_descriptor;  /* Descriptor template for objects in this    */
  901.                /* block.                    */
  902.    bool ok_relocate_descr;
  903.                /* Add object size in bytes to descriptor     */
  904.                /* template to obtain descriptor.  Otherwise    */
  905.                /* template is used as is.            */
  906.    bool ok_init;     /* Clear objects before putting them on the free list. */
  907. } GC_obj_kinds[MAXOBJKINDS];
  908. /* Predefined kinds: */
  909. # define PTRFREE 0
  910. # define NORMAL  1
  911. # define UNCOLLECTABLE 2
  912. # define STUBBORN 3
  913.  
  914. extern int GC_n_kinds;
  915.  
  916. extern word GC_n_heap_sects;    /* Number of separately added heap    */
  917.                 /* sections.                */
  918.  
  919. # ifdef MSWIN32
  920. extern word GC_n_heap_bases;    /* See GC_heap_bases.    */
  921. # endif
  922.  
  923. extern char * GC_invalid_map;
  924.             /* Pointer to the nowhere valid hblk map */
  925.             /* Blocks pointing to this map are free. */
  926.  
  927. extern struct hblk * GC_hblkfreelist;
  928.                 /* List of completely empty heap blocks    */
  929.                 /* Linked through hb_next field of     */
  930.                 /* header structure associated with    */
  931.                 /* block.                */
  932.  
  933. extern bool GC_is_initialized;        /* GC_init() has been run.    */
  934.  
  935. extern bool GC_objects_are_marked;    /* There are marked objects in  */
  936.                     /* the heap.            */
  937.  
  938. extern int GC_incremental;  /* Using incremental/generational collection. */
  939.  
  940. extern bool GC_dirty_maintained;/* Dirty bits are being maintained,     */
  941.                 /* either for incremental collection,    */
  942.                 /* or to limit the root set.        */
  943.  
  944. # ifndef PCR
  945.     extern ptr_t GC_stackbottom;    /* Cool end of user stack    */
  946. # endif
  947.  
  948. extern word GC_root_size;    /* Total size of registered root sections */
  949.  
  950. extern bool GC_debugging_started;    /* GC_debug_malloc has been called. */ 
  951.  
  952. extern ptr_t GC_least_plausible_heap_addr;
  953. extern ptr_t GC_greatest_plausible_heap_addr;
  954.             /* Bounds on the heap.  Guaranteed valid    */
  955.             /* Likely to include future heap expansion.    */
  956.             
  957. /* Operations */
  958. # ifndef abs
  959. #   define abs(x)  ((x) < 0? (-(x)) : (x))
  960. # endif
  961.  
  962.  
  963. /*  Marks are in a reserved area in                          */
  964. /*  each heap block.  Each word has one mark bit associated  */
  965. /*  with it. Only those corresponding to the beginning of an */
  966. /*  object are used.                                         */
  967.  
  968.  
  969. /* Mark bit perations */
  970.  
  971. /*
  972.  * Retrieve, set, clear the mark bit corresponding
  973.  * to the nth word in a given heap block.
  974.  *
  975.  * (Recall that bit n corresponds to object beginning at word n
  976.  * relative to the beginning of the block, including unused words)
  977.  */
  978.  
  979. # define mark_bit_from_hdr(hhdr,n) (((hhdr)->hb_marks[divWORDSZ(n)] \
  980.                 >> (modWORDSZ(n))) & (word)1)
  981. # define set_mark_bit_from_hdr(hhdr,n) (hhdr)->hb_marks[divWORDSZ(n)] \
  982.                 |= (word)1 << modWORDSZ(n)
  983.  
  984. # define clear_mark_bit_from_hdr(hhdr,n) (hhdr)->hb_marks[divWORDSZ(n)] \
  985.                 &= ~((word)1 << modWORDSZ(n))
  986.  
  987. /* Important internal collector routines */
  988.  
  989. void GC_apply_to_all_blocks(/*fn, client_data*/);
  990.             /* Invoke fn(hbp, client_data) for each     */
  991.             /* allocated heap block.            */
  992. struct hblk * GC_next_block(/* struct hblk * h */);
  993. void GC_mark_init();
  994. void GC_clear_marks();    /* Clear mark bits for all heap objects. */
  995. void GC_invalidate_mark_state();    /* Tell the marker that    marked        */
  996.                     /* objects may point to    unmarked   */
  997.                     /* ones, and roots may point to       */
  998.                     /* unmarked objects.           */
  999.                     /* Reset mark stack.           */
  1000. void GC_mark_from_mark_stack(); /* Mark from everything on the mark stack. */
  1001.                 /* Return after about one pages worth of   */
  1002.                 /* work.                   */
  1003. bool GC_mark_stack_empty();
  1004. bool GC_mark_some();    /* Perform about one pages worth of marking    */
  1005.             /* work of whatever kind is needed.  Returns    */
  1006.             /* quickly if no collection is in progress.    */
  1007.             /* Return TRUE if mark phase finished.        */
  1008. void GC_initiate_full();    /* initiate full collection.        */
  1009. void GC_initiate_partial();    /* initiate partial collection.        */            
  1010. void GC_push_all(/*b,t*/);    /* Push everything in a range         */
  1011.                 /* onto mark stack.            */
  1012. void GC_push_dirty(/*b,t*/);      /* Push all possibly changed         */
  1013.                   /* subintervals of [b,t) onto        */
  1014.                   /* mark stack.            */
  1015. #ifndef SMALL_CONFIG
  1016.   void GC_push_conditional(/* ptr_t b, ptr_t t, bool all*/);
  1017. #else
  1018. # define GC_push_conditional(b, t, all) GC_push_all(b, t)
  1019. #endif
  1020.                                 /* Do either of the above, depending    */
  1021.                 /* on the third arg.            */
  1022. void GC_push_all_stack(/*b,t*/);    /* As above, but consider        */
  1023.                     /*  interior pointers as valid      */
  1024. void GC_push_roots(/* bool all */); /* Push all or dirty roots.    */
  1025. extern void (*GC_push_other_roots)();
  1026.             /* Push system or application specific roots    */
  1027.             /* onto the mark stack.  In some environments    */
  1028.             /* (e.g. threads environments) this is        */
  1029.             /* predfined to be non-zero.  A client supplied */
  1030.             /* replacement should also call the original    */
  1031.             /* function.                    */
  1032. void GC_push_regs();    /* Push register contents onto mark stack.    */
  1033. void GC_remark();    /* Mark from all marked objects.  Used    */
  1034.              /* only if we had to drop something.    */
  1035. void GC_push_one(/*p*/);    /* If p points to an object, mark it    */
  1036.                 /* and push contents on the mark stack    */
  1037. void GC_push_one_checked(/*p*/); /* Ditto, omits plausibility test    */
  1038. void GC_push_marked(/* struct hblk h, hdr * hhdr */);
  1039.         /* Push contents of all marked objects in h onto    */
  1040.         /* mark stack.                        */
  1041. #ifdef SMALL_CONFIG
  1042. # define GC_push_next_marked_dirty(h) GC_push_next_marked(h)
  1043. #else
  1044.   struct hblk * GC_push_next_marked_dirty(/* h */);
  1045.         /* Invoke GC_push_marked on next dirty block above h.    */
  1046.         /* Return a pointer just past the end of this block.    */
  1047. #endif /* !SMALL_CONFIG */
  1048. struct hblk * GC_push_next_marked(/* h */);
  1049.         /* Ditto, but also mark from clean pages.    */
  1050. struct hblk * GC_push_next_marked_uncollectable(/* h */);
  1051.         /* Ditto, but mark only from uncollectable pages.    */
  1052. bool GC_stopped_mark(); /* Stop world and mark from all roots    */
  1053.             /* and rescuers.            */
  1054. void GC_clear_hdr_marks(/* hhdr */);  /* Clear the mark bits in a header */
  1055. void GC_add_roots_inner();
  1056. bool GC_is_static_root(/* ptr_t p */);
  1057.         /* Is the address p in one of the registered static    */
  1058.         /* root sections?                    */
  1059. void GC_register_dynamic_libraries();
  1060.         /* Add dynamic library data sections to the root set. */
  1061.  
  1062. /* Machine dependent startup routines */
  1063. ptr_t GC_get_stack_base();
  1064. void GC_register_data_segments();
  1065.  
  1066. /* Black listing: */
  1067. void GC_bl_init();     
  1068. # ifndef ALL_INTERIOR_POINTERS
  1069.     void GC_add_to_black_list_normal(/* bits */);
  1070.             /* Register bits as a possible future false    */
  1071.             /* reference from the heap or static data    */
  1072. #   define GC_ADD_TO_BLACK_LIST_NORMAL(bits) GC_add_to_black_list_normal(bits)
  1073. # else
  1074. #   define GC_ADD_TO_BLACK_LIST_NORMAL(bits) GC_add_to_black_list_stack(bits)
  1075. # endif
  1076.  
  1077. void GC_add_to_black_list_stack(/* bits */);
  1078. struct hblk * GC_is_black_listed(/* h, len */);
  1079.             /* If there are likely to be false references    */
  1080.             /* to a block starting at h of the indicated    */
  1081.             /* length, then return the next plausible    */
  1082.             /* starting location for h that might avoid    */
  1083.             /* these false references.            */
  1084. void GC_promote_black_lists();
  1085.             /* Declare an end to a black listing phase.    */
  1086. void GC_unpromote_black_lists();
  1087.             /* Approximately undo the effect of the above.    */
  1088.             /* This actually loses some information, but    */
  1089.             /* only in a reasonably safe way.        */
  1090.              
  1091. ptr_t GC_scratch_alloc(/*bytes*/);
  1092.                 /* GC internal memory allocation for    */
  1093.                 /* small objects.  Deallocation is not  */
  1094.                 /* possible.                */
  1095.     
  1096. /* Heap block layout maps: */            
  1097. void GC_invalidate_map(/* hdr */);
  1098.                 /* Remove the object map associated    */
  1099.                 /* with the block.  This identifies    */
  1100.                 /* the block as invalid to the mark    */
  1101.                 /* routines.                */
  1102. bool GC_add_map_entry(/*sz*/);
  1103.                 /* Add a heap block map for objects of    */
  1104.                 /* size sz to obj_map.            */
  1105.                 /* Return FALSE on failure.        */
  1106. void GC_register_displacement_inner(/*offset*/);
  1107.                 /* Version of GC_register_displacement    */
  1108.                 /* that assumes lock is already held    */
  1109.                 /* and signals are already disabled.    */
  1110.  
  1111. /*  hblk allocation: */        
  1112. void GC_new_hblk(/*size_in_words, kind*/);
  1113.                 /* Allocate a new heap block, and build */
  1114.                 /* a free list in it.            */                
  1115. struct hblk * GC_allochblk(/*size_in_words, kind*/);
  1116.                 /* Allocate a heap block, clear it if    */
  1117.                 /* for composite objects, inform    */
  1118.                 /* the marker that block is valid    */
  1119.                 /* for objects of indicated size.    */
  1120.                 /* sz < 0 ==> atomic.            */ 
  1121. void GC_freehblk();        /* Deallocate a heap block and mark it  */
  1122.                 /* as invalid.                */
  1123.                 
  1124. /*  Misc GC: */
  1125. void GC_init_inner();
  1126. bool GC_expand_hp_inner();
  1127. void GC_start_reclaim(/*abort_if_found*/);
  1128.                 /* Restore unmarked objects to free    */
  1129.                 /* lists, or (if abort_if_found is    */
  1130.                 /* TRUE) report them.            */
  1131.                 /* Sweeping of small object pages is    */
  1132.                 /* largely deferred.            */
  1133. void GC_continue_reclaim(/*size, kind*/);
  1134.                 /* Sweep pages of the given size and    */
  1135.                 /* kind, as long as possible, and    */
  1136.                 /* as long as the corr. free list is    */
  1137.                 /* empty.                */
  1138. void GC_reclaim_or_delete_all();
  1139.                 /* Arrange for all reclaim lists to be    */
  1140.                 /* empty.  Judiciously choose between    */
  1141.                 /* sweeping and discarding each page.    */
  1142. bool GC_reclaim_all(/* GC_stop_func f*/);
  1143.                 /* Reclaim all blocks.  Abort (in a    */
  1144.                 /* consistent state) if f returns TRUE. */
  1145. bool GC_block_empty(/* hhdr */); /* Block completely unmarked?     */
  1146. bool GC_never_stop_func();    /* Returns FALSE.        */
  1147. bool GC_try_to_collect_inner(/* GC_stop_func f */);
  1148.                 /* Collect; caller must have acquired    */
  1149.                 /* lock and disabled signals.        */
  1150.                 /* Collection is aborted if f returns    */
  1151.                 /* TRUE.  Returns TRUE if it completes    */
  1152.                 /* successfully.            */
  1153. # define GC_gcollect_inner() \
  1154.     (void) GC_try_to_collect_inner(GC_never_stop_func)
  1155. void GC_finish_collection();    /* Finish collection.  Mark bits are    */
  1156.                 /* consistent and lock is still held.    */
  1157. bool GC_collect_or_expand(/* needed_blocks */);
  1158.                 /* Collect or expand heap in an attempt */
  1159.                 /* make the indicated number of free    */
  1160.                 /* blocks available.  Should be called    */
  1161.                 /* until the blocks are available or    */
  1162.                 /* until it fails by returning FALSE.    */
  1163. void GC_init();            /* Initialize collector.        */
  1164. void GC_collect_a_little_inner(/* int n */);
  1165.                 /* Do n units worth of garbage         */
  1166.                 /* collection work, if appropriate.    */
  1167.                 /* A unit is an amount appropriate for  */
  1168.                 /* HBLKSIZE bytes of allocation.    */
  1169. ptr_t GC_generic_malloc(/* bytes, kind */);
  1170.                 /* Allocate an object of the given    */
  1171.                 /* kind.  By default, there are only    */
  1172.                 /* two kinds: composite, and atomic.    */
  1173.                 /* We claim it's possible for clever    */
  1174.                 /* client code that understands GC    */
  1175.                 /* internals to add more, e.g. to    */
  1176.                 /* communicate object layout info    */
  1177.                 /* to the collector.            */
  1178. ptr_t GC_generic_malloc_inner(/* bytes, kind */);
  1179.                 /* Ditto, but I already hold lock, etc.    */
  1180. ptr_t GC_generic_malloc_words_small(/*words, kind*/);
  1181.                 /* As above, but size in units of words */
  1182.                 /* Bypasses MERGE_SIZES.  Assumes    */
  1183.                 /* words <= MAXOBJSZ.            */
  1184. ptr_t GC_generic_malloc_inner_ignore_off_page(/* bytes, kind */);
  1185.                 /* Allocate an object, where        */
  1186.                 /* the client guarantees that there    */
  1187.                 /* will always be a pointer to the     */
  1188.                 /* beginning of the object while the    */
  1189.                 /* object is live.            */
  1190. ptr_t GC_allocobj(/* sz_inn_words, kind */);
  1191.                 /* Make the indicated             */
  1192.                 /* free list nonempty, and return its    */
  1193.                 /* head.                */
  1194.  
  1195. void GC_init_headers();
  1196. bool GC_install_header(/*h*/);
  1197.                 /* Install a header for block h.    */
  1198.                 /* Return FALSE on failure.        */
  1199. bool GC_install_counts(/*h, sz*/);
  1200.                 /* Set up forwarding counts for block    */
  1201.                 /* h of size sz.            */
  1202.                 /* Return FALSE on failure.        */
  1203. void GC_remove_header(/*h*/);
  1204.                 /* Remove the header for block h.    */
  1205. void GC_remove_counts(/*h, sz*/);
  1206.                 /* Remove forwarding counts for h.    */
  1207. hdr * GC_find_header(/*p*/);    /* Debugging only.            */
  1208.  
  1209. void GC_finalize();    /* Perform all indicated finalization actions    */
  1210.             /* on unmarked objects.                */
  1211.             /* Unreachable finalizable objects are enqueued    */
  1212.             /* for processing by GC_invoke_finalizers.    */
  1213.             /* Invoked with lock.                */
  1214. void GC_invoke_finalizers();     /* Run eligible finalizers.    */
  1215.                 /* Invoked without lock.    */    
  1216.             
  1217. void GC_add_to_heap(/*p, bytes*/);
  1218.             /* Add a HBLKSIZE aligned chunk to the heap.    */
  1219.  
  1220. void GC_print_obj(/* ptr_t p */);
  1221.             /* P points to somewhere inside an object with    */
  1222.             /* debugging info.  Print a human readable    */
  1223.             /* description of the object to stderr.        */
  1224. extern void (*GC_check_heap)();
  1225.             /* Check that all objects in the heap with     */
  1226.             /* debugging info are intact.  Print         */
  1227.             /* descriptions of any that are not.        */
  1228.             
  1229. /* Virtual dirty bit implementation:        */
  1230. /* Each implementation exports the following:    */
  1231. void GC_read_dirty();    /* Retrieve dirty bits.    */
  1232. bool GC_page_was_dirty(/* struct hblk * h  */);
  1233.             /* Read retrieved dirty bits.    */
  1234. bool GC_page_was_ever_dirty(/* struct hblk * h  */);
  1235.             /* Could the page contain valid heap pointers?    */
  1236. void GC_is_fresh(/* struct hblk * h, word number_of_blocks  */);
  1237.             /* Assert the region currently contains no    */
  1238.             /* valid pointers.                */
  1239. void GC_write_hint(/* struct hblk * h  */);
  1240.             /* h is about to be written.    */
  1241. void GC_dirty_init();
  1242.  
  1243. /* Slow/general mark bit manipulation: */
  1244. bool GC_is_marked();
  1245. void GC_clear_mark_bit();
  1246. void GC_set_mark_bit();
  1247.  
  1248. /* Stubborn objects: */
  1249. void GC_read_changed();    /* Analogous to GC_read_dirty */
  1250. bool GC_page_was_changed(/* h */);    /* Analogous to GC_page_was_dirty */
  1251. void GC_clean_changing_list();    /* Collect obsolete changing list entries */
  1252. void GC_stubborn_init();
  1253.  
  1254. /* Debugging print routines: */
  1255. void GC_print_block_list();
  1256. void GC_print_hblkfreelist();
  1257.  
  1258. /* Make arguments appear live to compiler */
  1259. void GC_noop();
  1260.  
  1261. /* Logging and diagnostic output:     */
  1262. void GC_printf(/* format, a, b, c, d, e, f */);
  1263.             /* A version of printf that doesn't allocate,    */
  1264.             /* is restricted to long arguments, and        */
  1265.             /* (unfortunately) doesn't use varargs for    */
  1266.             /* portability.  Restricted to 6 args and    */
  1267.             /* 1K total output length.            */
  1268.             /* (We use sprintf.  Hopefully that doesn't    */
  1269.             /* allocate for long arguments.)          */
  1270. # define GC_printf0(f) GC_printf(f, 0l, 0l, 0l, 0l, 0l, 0l)
  1271. # define GC_printf1(f,a) GC_printf(f, (long)a, 0l, 0l, 0l, 0l, 0l)
  1272. # define GC_printf2(f,a,b) GC_printf(f, (long)a, (long)b, 0l, 0l, 0l, 0l)
  1273. # define GC_printf3(f,a,b,c) GC_printf(f, (long)a, (long)b, (long)c, 0l, 0l, 0l)
  1274. # define GC_printf4(f,a,b,c,d) GC_printf(f, (long)a, (long)b, (long)c, \
  1275.                         (long)d, 0l, 0l)
  1276. # define GC_printf5(f,a,b,c,d,e) GC_printf(f, (long)a, (long)b, (long)c, \
  1277.                           (long)d, (long)e, 0l)
  1278. # define GC_printf6(f,a,b,c,d,e,g) GC_printf(f, (long)a, (long)b, (long)c, \
  1279.                         (long)d, (long)e, (long)g)
  1280.  
  1281. void GC_err_printf(/* format, a, b, c, d, e, f */);
  1282. # define GC_err_printf0(f) GC_err_puts(f)
  1283. # define GC_err_printf1(f,a) GC_err_printf(f, (long)a, 0l, 0l, 0l, 0l, 0l)
  1284. # define GC_err_printf2(f,a,b) GC_err_printf(f, (long)a, (long)b, 0l, 0l, 0l, 0l)
  1285. # define GC_err_printf3(f,a,b,c) GC_err_printf(f, (long)a, (long)b, (long)c, \
  1286.                           0l, 0l, 0l)
  1287. # define GC_err_printf4(f,a,b,c,d) GC_err_printf(f, (long)a, (long)b, \
  1288.                             (long)c, (long)d, 0l, 0l)
  1289. # define GC_err_printf5(f,a,b,c,d,e) GC_err_printf(f, (long)a, (long)b, \
  1290.                               (long)c, (long)d, \
  1291.                               (long)e, 0l)
  1292. # define GC_err_printf6(f,a,b,c,d,e,g) GC_err_printf(f, (long)a, (long)b, \
  1293.                             (long)c, (long)d, \
  1294.                             (long)e, (long)g)
  1295.             /* Ditto, writes to stderr.            */
  1296.             
  1297. void GC_err_puts(/* char *s */);
  1298.             /* Write s to stderr, don't buffer, don't add    */
  1299.             /* newlines, don't ...                */
  1300.  
  1301. # endif /* GC_PRIVATE_H */
  1302.